//
//  PropertiesAndMethodsViewController.m
//  MyFramework
//
//  Created by 余洋 on 2018/8/14.
//  Copyright © 2018年 余洋. All rights reserved.
//

#import "PropertiesAndMethodsViewController.h"

#import <objc/runtime.h>
#import "NSObject+NNAddAttribute.h"

#import "PersonModel.h"

@interface PropertiesAndMethodsViewController ()

@property (nonatomic, strong) PersonModel *person;
@property (weak, nonatomic) IBOutlet UILabel *testLabel;
@property (nonatomic, strong) NSObject *personForAddAttributesDynamically;

@end

@implementation PropertiesAndMethodsViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - action
- (IBAction)clickBtnAction:(id)sender {
    if (self.type == PropertiesAndMethodTypeChangeProperties) {
        [self changePropertyValues];
    } else if (self.type == PropertiesAndMethodTypeAddAttributesDynamically) {
        [self addAttributesDynamically];
    }
}

/**
 更改属性值
 */
- (void)changePropertyValues {
    //整型前加上unsigned关键字后，将它变成无符号整型，最高位不是符号位，而是数值位。无符号整数不能表示负数，但是表示范围大了。
    unsigned int count = 0;
    //动态获取类中的所有属性（包括私有）
    Ivar *ivar = class_copyIvarList(self.person.class, &count);
    //遍历属性找到对应字段
    for (int i=0; i<count; i++) {
        Ivar tempIvar = ivar[i];
        //被const关键字修饰的实例变量,在初始化之后,其值就不能改变了,
        const char *varchar = ivar_getName(tempIvar);
        NSString *varString = [NSString stringWithUTF8String:varchar];
        if ([varString isEqualToString:@"_name"]) {
            // 修改对应的字段值
            object_setIvar(self.person, tempIvar, @"Eric");
            break;
        }
    }
    self.testLabel.text = self.person.name.length ? self.person.name : @"更改属性值失败";
}

/**
 动态添加属性
 */
- (void)addAttributesDynamically {
    self.personForAddAttributesDynamically = [NSObject new];
    self.personForAddAttributesDynamically.name = @"Eric";
    self.testLabel.text = self.personForAddAttributesDynamically.name.length ? self.personForAddAttributesDynamically.name : @"添加属性失败";
}

#pragma mark - 懒加载
- (PersonModel *)person {
    if (!_person) {
        _person = [PersonModel new];
    }
    return _person;
}
@end
